import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import '../Gesture/GestureDetectorHitTest.dart';

///组合动画用法
///
///抽奖滚动动画 stack的组合
///
///
///
///

class PointOffset {
  Offset point;
  bool isEnd;
  static List<PointOffset> _pointOffset = <PointOffset>[];

  PointOffset.name(this.point, this.isEnd);
}

class CanvasPointScroll3 extends StatefulWidget {
  @override
  _CanvasPointScrollState3 createState() => _CanvasPointScrollState3();
}

class _CanvasPointScrollState3 extends State<CanvasPointScroll3> {
  //布局
  final GlobalKey containWidgetGlobalKey = GlobalKey();

  var _scrollController = ScrollController();

  //画布
  late BoardPainterWidget canvasWidget;

  //局部刷新
  late CounterNotify counterNotify;

  bool isScroll = true;

  @override
  void initState() {
    super.initState();
    counterNotify = CounterNotify();

    Future.delayed(Duration(milliseconds: 5000), () {
      counterNotify.addValue(400);
    });

    canvasWidget = BoardPainterWidget(containWidgetGlobalKey);
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: SingleChildScrollView(
          physics: isScroll ? null : NeverScrollableScrollPhysics(),
          controller: _scrollController,
          child: Stack(
            children: [
              ListView(
                shrinkWrap: true,
                physics: new NeverScrollableScrollPhysics(),
                key: containWidgetGlobalKey,
                children: [
                  Column(
                    children: [
                      // Container(
                      //   color: Color(0xFF15C9E8),
                      //   width: 100,
                      //   height: 400,
                      // ),
                      // Container(
                      //   color: Color(0xFF300C92),
                      //   width: 400,
                      //   height: 400,
                      // ),
                      // Container(
                      //   color: Color(0xFFB41C89),
                      //   width: 400,
                      //   height: 400,
                      // ),
                      // TextButton(
                      //     onPressed: () {
                      //       print("按钮");
                      //       isScroll = !isScroll;
                      //       setState(() {
                      //
                      //       });
                      //     },
                      //     child: Text("data")),
                      // TextField(),
                      ValueListenableBuilder<double>(
                        builder: (BuildContext context, value, Widget? child) {
                          return Container(
                            color: Color(0xFF1947EE),
                            width: 400,
                            height: value,
                          );
                        },
                        valueListenable: counterNotify.countListenable,
                      )
                    ],
                  ),
                ],
              ),
              canvasWidget
            ],
          ),
        ),
      ),
    );
  }
}

class CounterNotify with ChangeNotifier {
  ValueNotifier<double> _countListenable = ValueNotifier<double>(0.0);

  ValueNotifier<double> get countListenable => _countListenable;

  void addValue(double i) {
    _countListenable.value += i;
  }
}

class BoardPainterWidget extends StatefulWidget {
  GlobalKey containWidgetGlobalKey;

  BoardPainterWidget(this.containWidgetGlobalKey);

  // void Function(double move)? callMoveBack;

  // void getMoveDistance(double move){
  //    print("getMoveDistance--:$move");
  //    _state.getMoveDistance(move);
  // }

  _BoardPainterWidgetState _state = _BoardPainterWidgetState();

  @override
  _BoardPainterWidgetState createState() {
    return _state;
  }
}

class _BoardPainterWidgetState extends State<BoardPainterWidget> {
  /// 已描绘的点
  List<PointOffset> _pointOffset = <PointOffset>[];

  final GlobalKey containWidgetGlobalKey = GlobalKey();

  //一屏的高度
  double screenHeight = 0;

  //画布的高度
  double _gestureDetectorHeight = 0;
  double _gestureDetectorWidth = 0;

  late ValueNotifier<List<PointOffset>> _pointListenable;

  /// 添加点，注意不要超过Widget范围
  _addPoint(PointerMoveEvent details) {
    Size? referenceBox = widget.containWidgetGlobalKey.currentContext?.size;
    double maxW = referenceBox?.width ?? 0;
    double maxH = referenceBox?.height ?? 0;
    // 校验范围
    if (details.localPosition.dx <= 0 || details.localPosition.dy <= 0) return;
    if (details.localPosition.dx > maxW || details.localPosition.dy > maxH)
      return;

    // print("_addPoint $_gestureDetectorHeight");
    // setState(() {
    //   _pointOffset = List.from(_pointOffset)
    //     ..add(PointOffset.name(details.localPosition, true));
    // });
    //listener监听，不会影响整棵树的绘制
    _pointOffset = List.from(_pointOffset)
      ..add(PointOffset.name(details.localPosition, true));
    _pointListenable.value = _pointOffset;
  }

  void moveCallback(double move) {}

  @override
  void initState() {
    super.initState();
    _pointListenable = ValueNotifier<List<PointOffset>>(_pointOffset);

    WidgetsBinding.instance?.addPostFrameCallback((_) {
      _gestureDetectorHeight =
          widget.containWidgetGlobalKey.currentContext?.size?.height ?? 0;
      _gestureDetectorWidth =
          widget.containWidgetGlobalKey.currentContext?.size?.width ?? 0;
      print("绘制完成1：$_gestureDetectorHeight");
      WidgetsBinding.instance?.addPersistentFrameCallback((_) {
        print("实时Frame绘制回调"); //每帧都回调
        var widgetHeight =
            widget.containWidgetGlobalKey.currentContext?.size?.height ?? 0;

        if (widgetHeight != _gestureDetectorHeight &&
            widgetHeight > _gestureDetectorHeight) {



          print("绘制完成2：$_gestureDetectorHeight");
          setState(() {
            _gestureDetectorHeight = widgetHeight;
            _gestureDetectorWidth =
                widget.containWidgetGlobalKey.currentContext?.size?.width ?? 0;
          });
        }
      });

      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
       Listener(
                onPointerMove: (details) {
                  print(
                      "object:${details.localPosition}----${details.distance}");
                  _addPoint(details);
                },
                onPointerUp: (details) {
                  _pointOffset.add(PointOffset.name(Offset.zero, false));
                },
                child: Container(
                  height: _gestureDetectorHeight,
                  width: _gestureDetectorWidth,
                  color: Color(0xFFEA0C0C),
                )),
        RepaintBoundary(
            //隔离重绘控件，singlescrollview 滑动发生重绘，导致画笔paint响应
            child: CustomPaint(
                painter: BoardPainter(
                    points: _pointOffset, factor: _pointListenable))),
      ],
    );
  }
}

class BoardPainter extends CustomPainter {
  final ValueNotifier<List<PointOffset>>? factor;

  BoardPainter({required this.points, this.factor}) : super(repaint: factor);

  List<PointOffset> points;

  void paint(Canvas canvas, Size size) {
    points = factor?.value ?? points;
    print("绘制 paint1 ${points.length}-- ${factor?.value.length}");
    if (points == null) {
      return;
    }
    Paint paint = Paint()
      ..color = Colors.black
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 5.0;
    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null &&
          points[i + 1] != null &&
          points[i + 1].isEnd &&
          points[i].isEnd) {
        // print("绘制 paint${points[i].point}----${points[i + 1].point}");

        canvas.drawLine(points[i].point, points[i + 1].point, paint);
      }
    }
  }

  bool shouldRepaint(BoardPainter other) {
    // print("绘制 shouldRepaint--:${other.points != points}");
    return other.points != points;
  }
}

class _HitTestBlocker extends SingleChildRenderObjectWidget {
  _HitTestBlocker({
    Key? key,
    this.blocker = true,
    Widget? child,
  }) : super(key: key, child: child);

  final bool blocker;

  @override
  RenderObject createRenderObject(BuildContext context) {
    return _RenderHitTestBlocker(blocker: blocker);
  }

  @override
  void updateRenderObject(
      BuildContext context, _RenderHitTestBlocker renderObject) {
    renderObject..blocker = blocker;
  }
}

class _RenderHitTestBlocker extends RenderProxyBox {
  _RenderHitTestBlocker({this.blocker = true});

  bool blocker;

  @override
  bool hitTest(BoxHitTestResult result, {required Offset position}) {
    if (blocker) {
      hitTestChildren(result, position: position);
      return false;
    } else {
      return super.hitTest(result, position: position);
    }
  }

  @override
  bool hitTestSelf(Offset position) => !blocker;
}
